package example.com.nexd.collectionsdk.sdk.collector.core;

import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;

import java.util.concurrent.TimeUnit;

import example.com.nexd.collectionsdk.sdk.collector.BluetoothCollector;
import example.com.nexd.collectionsdk.sdk.collector.Collector;
import example.com.nexd.collectionsdk.sdk.collector.CollectorConfig;
import example.com.nexd.collectionsdk.sdk.collector.UserIdUtils;
import example.com.nexd.collectionsdk.sdk.collector.bean.BluetoothDataResult;
import example.com.nexd.collectionsdk.sdk.collector.listener.BluetoothCollrctorResultListener;
import example.com.nexd.collectionsdk.sdk.collector.listener.DefaultCollectorResultListener;
import example.com.nexd.collectionsdk.sdk.core.SimpleSafeTask;
import example.com.nexd.collectionsdk.sdk.core.TaskExecutor;
import example.com.nexd.collectionsdk.sdk.utils.Log;
import example.com.nexd.collectionsdk.sdk.utils.ObjectPool;


/**
 * BluetoothCollectorTask create by codingfish at 15/4/29
 * TODO:
 *
 * @Version V1.0
 */
final class BluetoothCollectorTask extends BluetoothCollector {
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothBroadcastReceiver bluetoothBroadcastReceiver;
    private BluetoothHanlder bluetoothHanlder;
    private final static int OBJECT_POOL_SIZE = 50;
    private ObjectPool<BluetoothDataResult> bluetoothDataResultObjectPool;
    private final static int NORMARL_SUCCESS_CODE = 10010;
    public BluetoothCollectorTask(Context context, BluetoothCollrctorResultListener bluetoothCollrctorResultListener, CollectorConfig collectorConfig) {
        super(context, bluetoothCollrctorResultListener, collectorConfig);

        ObjectPool.ObjectPoolFactory<BluetoothDataResult> bluetoothDataResultObjectPoolFactory = new ObjectPool.ObjectPoolFactory<BluetoothDataResult>() {
            @Override
            public BluetoothDataResult createObject() {
                return new BluetoothDataResult();
            }
        };

        bluetoothDataResultObjectPool = new ObjectPool<>(bluetoothDataResultObjectPoolFactory, OBJECT_POOL_SIZE);
    }

    public BluetoothCollectorTask(Context context, CollectorConfig collectorConfig) {
        super(context, null, collectorConfig);
        ObjectPool.ObjectPoolFactory<BluetoothDataResult> bluetoothDataResultObjectPoolFactory = new ObjectPool.ObjectPoolFactory<BluetoothDataResult>() {
            @Override
            public BluetoothDataResult createObject() {
                return new BluetoothDataResult();
            }
        };

        bluetoothDataResultObjectPool = new ObjectPool<>(bluetoothDataResultObjectPoolFactory, OBJECT_POOL_SIZE);
    }

    public BluetoothCollectorTask(Context context) {
        super(context, null, null);
    }

    public BluetoothCollectorTask(Context context, BluetoothCollrctorResultListener bluetoothCollrctorResultListener) {
        super(context, bluetoothCollrctorResultListener, null);
        ObjectPool.ObjectPoolFactory<BluetoothDataResult> bluetoothDataResultObjectPoolFactory = new ObjectPool.ObjectPoolFactory<BluetoothDataResult>() {
            @Override
            public BluetoothDataResult createObject() {
                return new BluetoothDataResult();
            }
        };

        bluetoothDataResultObjectPool = new ObjectPool<>(bluetoothDataResultObjectPoolFactory, OBJECT_POOL_SIZE);
    }

    @Override
    public boolean initilazeCollector() {
        //非空判断
        if (bluetoothCollrctorResultListener == null) {
            bluetoothCollrctorResultListener = DefaultCollectorResultListener.getBluetoothDefaultCollectorResultListener();
        }

        if (collectorConfig == null) {
            collectorConfig = new CollectorConfig.Builder().build();
        }

        if (context == null) {
            bluetoothCollrctorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_CONTEXT_NULL, "context is null");
            return false;
        }

        if (!(checkPermission("android.permission.BLUETOOTH") & checkPermission("android.permission.BLUETOOTH_ADMIN"))) {
            bluetoothCollrctorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAIED_ID_NO_PERMISSION, "木有权限");
            return false;
        }

        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (bluetoothAdapter == null) {
            bluetoothCollrctorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_UNSUPPORTED_SENSOR_TYPE, "unsupported sensor");
            return false;
        }

        if (!bluetoothAdapter.isEnabled()) {
            //没有打开蓝牙
            if (collectorConfig.collector_enable_mode == Collector.bluetooth_enable_mode_auto) {
                //自动打开
                bluetoothAdapter.enable();
            } else {
                // 手动打开
                bluetoothCollrctorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAIED_ID_COLLECTOR_STATE_OFF, "sensor off");
                return false;
            }
        }

        if (bluetoothAdapter.getScanMode() == BluetoothAdapter.SCAN_MODE_NONE) {
            //该蓝牙不能扫描以及被扫描
            bluetoothCollrctorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_SCAN_MODE_NONE, "该蓝牙不能扫描以及被扫描");
            return false;
        }


        return true;
    }

    @Override
    public boolean startCollector() {
        //启动定时器，用于循环
//
//        Intent intent = new Intent(context, BluetoothBroadcastReceiver.class);
//        intent.setAction("action_bluetooth_collector_wakeup");
//        PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
//
//        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
//        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), collectorConfig.bluetooth_delay, sender);

        Log.d(TAG, "startCollector");

        // Register the BroadcastReceiver

        bluetoothHanlder = new BluetoothHanlder();

        bluetoothBroadcastReceiver = new BluetoothBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
//        filter.addAction("action_bluetooth_collector_wakeup");
        context.registerReceiver(bluetoothBroadcastReceiver, filter);


        TaskExecutor.startDelayedTask(new BluetoothCollectorThread(), collectorConfig.collector_delay, TimeUnit.MILLISECONDS);
        return true;
    }

    @Override
    public boolean stopCollector() {
        if (bluetoothHanlder != null) {
            bluetoothHanlder = null;
        }

        if (bluetoothBroadcastReceiver != null) {
            context.unregisterReceiver(bluetoothBroadcastReceiver);
        }


        bluetoothCollrctorResultListener = null;
        bluetoothAdapter = null;
        return true;
    }

    private class BluetoothCollectorThread extends SimpleSafeTask {


        @Override
        protected Object doInBackgroundSafely() throws Exception {

//            if (bluetoothAdapter != null) {
//                bluetoothAdapter.disable();
//                bluetoothAdapter.enable();
//            }

            if (bluetoothAdapter.isDiscovering()) {
                //蓝牙设备正在扫描。检查是否取消扫描成功，如果成功，则开启扫描。如果失败，则重启 Adapter 并重启线程。
                Log.d(TAG, "bluetooth device scan is running!");
                if (!bluetoothAdapter.cancelDiscovery()) {
                    Log.d(TAG, "bluetooth device cancelDiscovery failed!");
                    //停止失败
                    bluetoothAdapter.disable();
                    bluetoothAdapter.enable();
                    if (bluetoothHanlder != null) {
                        bluetoothHanlder.sendEmptyMessage(10011);
                    }
                    return null;
                } else {

                    if (!bluetoothAdapter.startDiscovery()) {
                        //启动失败
                        bluetoothAdapter.disable();
                        bluetoothAdapter.enable();
                        if (bluetoothHanlder != null) {
                            bluetoothHanlder.sendEmptyMessage(10011);
                        }
                        return null;
                    } else {
                        //启动成功
                        Thread.sleep(collectorConfig.bluetooth_delay - 1);
                        bluetoothAdapter.cancelDiscovery();
                    }
                    Log.d(TAG, "bluetooth device cancelDiscovery success and startDiscovery success !");
                }
            } else {
                //没有扫描
                if (!bluetoothAdapter.startDiscovery()) {
                    Log.d(TAG, "bluetooth device startDiscovery failed! 没有扫描");
                    //启动失败
                    bluetoothAdapter.disable();
                    bluetoothAdapter.enable();
                    if (bluetoothHanlder != null) {
                        bluetoothHanlder.sendEmptyMessage(10011);
                    }
                    return null;
                } else {
                    //启动成功
                    Thread.sleep(collectorConfig.bluetooth_delay / 2);
                    bluetoothAdapter.cancelDiscovery();
                }
            }

            //发送消息，启动循环
            if (bluetoothHanlder != null) {
                bluetoothHanlder.sendEmptyMessage(NORMARL_SUCCESS_CODE);
            }
            return null;
        }
    }


    private class BluetoothHanlder extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case NORMARL_SUCCESS_CODE:
                    TaskExecutor.startDelayedTask(new BluetoothCollectorThread(), collectorConfig.bluetooth_delay, TimeUnit.MILLISECONDS);
                    break;

                /*重启采集线程。重启的等待时间为原有延时的一半*/
                case 10011:
                    TaskExecutor.startDelayedTask(new BluetoothCollectorThread(), collectorConfig.bluetooth_delay / 2, TimeUnit.MILLISECONDS);
                    break;
            }
        }
    }

    private class BluetoothBroadcastReceiver extends BroadcastReceiver {
        /*用于存放一次采集周期中的所有 Mac 地址*/
//        private List<String> bluetoothAddresses;

        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                //扫描开始
//                bluetoothAddresses = new ArrayList<String>();
                Log.d(TAG, "ACTION_DISCOVERY_STARTED");
            } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                //发现设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device != null) {
                    BluetoothDataResult result = new BluetoothDataResult();
                    result.setUserId(UserIdUtils.getInstance().getUserId(context));
                    result.setAddress(device.getAddress());
                    result.setBoundState(device.getBondState());
                    result.setId(UserIdUtils.getInstance().getTask_Id());
                    result.setName(device.getName());
                    result.setRssi(intent.getExtras().getShort(BluetoothDevice.EXTRA_RSSI));
                    result.setTimestamp(SystemClock.currentThreadTimeMillis());
                    if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                        result.setType(device.getType());
                    } else {
                        result.setType(0);
                    }

                    if (result != null && bluetoothCollrctorResultListener != null) {
                        bluetoothCollrctorResultListener.onSuccess(UserIdUtils.getInstance().getTask_Id(), result);
                    } else {
                        if (bluetoothCollrctorResultListener != null) {
                            bluetoothCollrctorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAIED_ID_RESULT_NULL, "结果为空");
                        }
                    }

//                    bluetoothDataResultObjectPool.free(result);
//                    bluetoothDataResults.add(result);
                }

                Log.d(TAG, "ACTION_DISCOVERY_FOUND");
            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                //扫描结束
                Log.d(TAG, "ACTION_DISCOVERY_FINISHED");
            }
        }
    }
}
